package com.sw.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.web3j.abi.EventEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Event;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.http.HttpService;
import rx.Subscription;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;

/**
 * @program: demo
 * @description:
 * @author: Wangzheng
 * @create: 2020-12-21 14:13
 **/

public class Filter {

    @Autowired
    private static Web3j web3j;

    @Autowired
    private static Subscription subscription;


    /**
     * 新区块监听
     * http://localhost:8080/Filter/newBlockFilter
     */
    String normal = "http://localhost:8545";

    public void newBlockFilter() {
        subscription = Web3j.build(new HttpService(normal)).
                blockObservable(false).
                subscribe(block -> {
                    System.out.println("=========new block come in===========");
                    System.out.println("block number" + block.getBlock().getNumber());
                    System.out.println("block hash" + block.getBlock().getHash());
                    System.out.println("block Transactions" + block.getBlock().getTransactions());
                    System.out.println("block ExtraData" + block.getBlock().getExtraData());
                    System.out.println("block Timestamp" + block.getBlock().getTimestamp());
                    System.out.println("block Miner" + block.getBlock().getMiner());
                    System.out.println("block Author" + block.getBlock().getAuthor());
                    System.out.println("block GasLimit" + block.getBlock().getGasLimit());
                    System.out.println("block GasUsed" + block.getBlock().getGasUsed());
                    System.out.println("block TransactionsRoot" + block.getBlock().getTransactionsRoot().toString());
                    System.out.println("block ParentHash" + block.getBlock().getParentHash());
                    System.out.println("block Size" + block.getBlock().getSize());
                    System.out.println("block Nonce" + block.getBlock().getNonce());
                    System.out.println("block GasUsedRaw" + block.getBlock().getGasUsedRaw());
                    System.out.println("=========over===========");
                });
    }

    /**
     * 新交易监听 拿到交易的 transactionHash
     * http://localhost:8080/Filter/newTransactionFilter
     */

    public void newTransactionFilter() {
        subscription = Web3j.build(new HttpService(normal)).
                transactionObservable().
                subscribe(transaction -> {
                    System.out.println("=========transaction come in===========");
                    System.out.println("transaction Hash " + " : " + transaction.getHash());
                    System.out.println("transaction BlockHash " + " : " + transaction.getBlockHash());
                    System.out.println("transaction To " + " : " + transaction.getTo());
                    System.out.println("transaction From " + " : " + transaction.getFrom());
                    System.out.println("transaction Input " + " : " + transaction.getInput());
                    System.out.println("transaction PublicKey " + " : " + transaction.getPublicKey());
                    System.out.println("transaction BlockNumberRaw " + " : " + transaction.getBlockNumberRaw());
                    System.out.println("transaction BlockNumber " + " : " + transaction.getBlockNumber());
                    System.out.println("transaction Creates " + " : " + transaction.getCreates());
                    System.out.println("transaction GasPriceRaw " + " : " + transaction.getGasPriceRaw());
                    System.out.println("transaction GasPrice " + " : " + transaction.getGasPrice());
                    System.out.println("transaction Nonce " + " : " + transaction.getNonce());
                    System.out.println("transaction Value " + " : " + transaction.getValue());
                    System.out.println("transaction ValueRaw " + " : " + transaction.getValueRaw());
                    System.out.println("=========over===========");
                });

    }

    /**
     * 遍历旧区块、交易
     * http://localhost:8080/Filter/replayFilter/0/100000
     */

    public void replayFilter(Integer start, Integer end) {
        BigInteger startBlock = BigInteger.valueOf(start);
        BigInteger endBlock = BigInteger.valueOf(end);

        //遍历旧区块
        subscription = Web3j.build(new HttpService(normal)).
                replayBlocksObservable(
                        DefaultBlockParameter.valueOf(startBlock),
                        DefaultBlockParameter.valueOf(endBlock),
                        false).
                subscribe(ethBlock -> {
                    System.out.println("=================区块信息 start =====================");
                    System.out.println("Number" + " : " + ethBlock.getBlock().getNumber());
                    System.out.println(ethBlock.getBlock().getTransactions());
                    System.out.println(ethBlock.getBlock().getTimestamp());
                    System.out.println(ethBlock.getBlock().getHash());
                    System.out.println(ethBlock.getBlock().getMiner());
                    System.out.println(ethBlock.getBlock().getAuthor());
                    System.out.println(ethBlock.getBlock().getExtraData());
                    System.out.println(ethBlock.getBlock().getGasLimit());
                    System.out.println(ethBlock.getBlock().getGasUsed());
                    System.out.println(ethBlock.getBlock().getGasUsedRaw());
                    System.out.println(ethBlock.getBlock().getNonce());
                    System.out.println(ethBlock.getBlock().getParentHash());
                    System.out.println(ethBlock.getBlock().getSize());
                    System.out.println(ethBlock.getBlock().getTransactionsRoot());
                    System.out.println(ethBlock.getBlock().getDifficulty());
                    System.out.println(ethBlock.getBlock().getDifficultyRaw());
                    System.out.println(ethBlock.getBlock().getGasLimitRaw());
                    System.out.println(ethBlock.getBlock().getLogsBloom());
                    System.out.println(ethBlock.getBlock().getTimestampRaw());
                    System.out.println("=================区块信息 over =====================");
                });
        //遍历旧交易
        subscription = Web3j.build(new HttpService(normal)).
                replayTransactionsObservable(
                        DefaultBlockParameter.valueOf(startBlock),
                        DefaultBlockParameter.valueOf("latest")).
                subscribe(transaction -> {
                    System.out.println("=========遍历旧交易 star ===========");
                    System.out.println("transaction Hash " + " : " + transaction.getHash());
                    System.out.println("transaction BlockHash " + " : " + transaction.getBlockHash());
                    System.out.println("transaction To " + " : " + transaction.getTo());
                    System.out.println("transaction From " + " : " + transaction.getFrom());
                    System.out.println("transaction Input " + " : " + transaction.getInput());
                    System.out.println("transaction PublicKey " + " : " + transaction.getPublicKey());
                    System.out.println("transaction BlockNumberRaw " + " : " + transaction.getBlockNumberRaw());
                    System.out.println("transaction BlockNumber " + " : " + transaction.getBlockNumber());
                    System.out.println("transaction Creates " + " : " + transaction.getCreates());
                    System.out.println("transaction GasPriceRaw " + " : " + transaction.getGasPriceRaw());
                    System.out.println("transaction GasPrice " + " : " + transaction.getGasPrice());
                    System.out.println("transaction Nonce " + " : " + transaction.getNonce());
                    System.out.println("transaction Value " + " : " + transaction.getValue());
                    System.out.println("transaction ValueRaw " + " : " + transaction.getValueRaw());
                    System.out.println("=========遍历旧交易 over ===========");
                });
    }


    /**
     * Event log相关
     * 监听合约event
     */

    public void ContractEvent(String contractAddress) {
        Web3j web3j = Web3j.build(new HttpService(normal));
        while (true) {
            EthFilter filter = new EthFilter(
                    DefaultBlockParameterName.EARLIEST,
                    DefaultBlockParameterName.LATEST,
                    contractAddress);
            Event event = new Event("Transfer",
                    Arrays.<TypeReference<?>>asList(
                            new TypeReference<Address>() {
                            },
                            new TypeReference<Address>() {
                            }
                    ),
                    Arrays.<TypeReference<?>>asList(
                            new TypeReference<Uint256>() {
                            }
                    )
            );

            String topicData = EventEncoder.encode(event);
            filter.addSingleTopic(topicData);
            System.out.println(topicData);

            web3j.ethLogObservable(filter).subscribe(log -> {
                System.out.println(log.getBlockNumber());
                System.out.println(log.getTransactionHash());
                List<String> topics = log.getTopics();
                for (String topic : topics) {
                    System.out.println(topic);
                }
            });
        }

    }

}